package modelo;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Random;
import modelo.naves.Naves;
import modelo.naves.NavesEnemigas;
import modelo.util.ContadorSimple;

public class FlotaEnemiga{

	private LinkedList<GeneradorNave> generadores;
	private ContadorSimple llamadasTieneNaves;
	private NavesEnemigas guia;
	private ArrayList<NavesEnemigas> naves;
	private int retardoCreacion;

	public FlotaEnemiga(int retardoCreacion) {
		this.retardoCreacion = retardoCreacion;
		llamadasTieneNaves = new ContadorSimple(retardoCreacion);
		cargarCreadoresDeNaves();
		this.crearNaves();
	}

	public NavesEnemigas getGuia() {
		return guia;
	}

	private void reiniciarLlamadasTieneNaves() {
		this.llamadasTieneNaves = new ContadorSimple(retardoCreacion);
	}

	public Naves getNave() {
		if (this.naves.size() < 0)
			throw new NoHayNavesException();
		return naves.remove(0);
	}

	public Naves getNaveSinChequeo() {
		return naves.remove(0);
	}

	public void actualizar() {
		if (!guia.seguirActuando() |  naves.size() == 0)
			this.crearNaves();
	}

	/*
	 * este chequeo es para evitar que las naves se superpongan
	 */
	public boolean tieneNaves() {
		if (llamadasTieneNaves.agotado()) {
			reiniciarLlamadasTieneNaves();
			return hayNaves();
		}
		llamadasTieneNaves.descontar();
		return false;
	}

	private boolean hayNaves() {
		return (naves.size() > 0 & guia.seguirActuando());
	}

	private void crearNaves() {
		GeneradorNave generador = getCreadorNave();
		// cantidad aleatoria con minimo de 15 naves
		int cantNaves = (((int) Math.random() * 4) + 15);
		this.naves = new ArrayList<NavesEnemigas>();
		NavesEnemigas unGuia = (NavesEnemigas) generador.getNave();
		unGuia.setGuia(unGuia);
		guia = unGuia;
		// crear todas las naves
		for (int i = 0; i < cantNaves; i++) {
			NavesEnemigas nave = (NavesEnemigas) generador.getNave();
			nave.setGuia(unGuia);
			naves.add(nave);
		}
		// agregar al guia una posicion aleatoria
		Random rand = new Random();
		int i = rand.nextInt(naves.size());
		naves.add(i, unGuia);
	}
	
	private void cargarCreadoresDeNaves(){
		generadores = new LinkedList<GeneradorNave> ();
		generadores.add(new CreadorAvionetas());
		generadores.add(new CreadorBombarderos());
		generadores.add(new CreadorExploradores());
		generadores.add(new CreadorCazas());
		generadores.add(new CreadorCazasEspeciales());
	}

	private GeneradorNave getCreadorNave(){
		try {
			GeneradorNave generador = generadores.removeFirst();
			generadores.addLast(generador);
			return generador;
		}
		catch (NoSuchElementException e){
			throw new NivelesAgotadosException();
		}
	}
}
